package com.junsi.web.controller.system;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSON;
import com.junsi.common.core.controller.BaseController;
import com.junsi.common.core.domain.AjaxResult;
import com.junsi.common.utils.ServletUtils;
import com.junsi.common.utils.StringUtils;
import com.junsi.common.utils.http.HttpUtils;
import com.junsi.framework.util.ShiroUtils;
import com.junsi.system.domain.SysUser;
import com.junsi.system.service.ISysUserService;
import com.junsi.system.vo.SSoUserInfo;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * 登录验证
 *
 * @author junsi
 */
@Controller
public class SysLoginController extends BaseController
{

	/**
	 * 认证接口
	 */
	@Value("${sso.oauth.client_url}")
	private String clientUrl;

	@Value("${sso.oauth.client_id}")
	private String clientId;

	@Value("${sso.oauth.response_type}")
	private String responseType;

	@Value("${sso.oauth.redirect_uri}")
	private String redirectUri;

	/**
	 * 获取授权接口
	 */
	@Value("${sso.getToken.client_url}")
	private String tokenUrl;

	@Value("${sso.getToken.client_secret}")
	private String clientSecret;

	@Value("${sso.getToken.grant_type}")
	private String grantType;

	/**
	 * 获取用户信息接口
	 */
	@Value("${sso.user.client_url}")
	private String userInfoUrl;

	/**
	 * 获取用户信息接口
	 */
	@Value("${sso.user.success_redirect_uri}")
	private String successRedirectUri;

	/**
	 * 统一无权友好页面
	 */
	@Value("${sso.nooauth.url}")
	private String nooauthUrl;


	@Autowired
	private ISysUserService userService;

	@GetMapping("/login")
	public String login(HttpServletRequest request, HttpServletResponse response)
	{
		// 如果是Ajax请求，返回Json字符串。
		if (ServletUtils.isAjaxRequest(request))
		{
			return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}");
		}

		return "login";
	}

	@PostMapping("/login")
	@ResponseBody
	public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe)
	{
		UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
		Subject subject = SecurityUtils.getSubject();
		try
		{
			subject.login(token);
			return success();
		}
		catch (AuthenticationException e)
		{
			String msg = "用户或密码错误";
			if (StringUtils.isNotEmpty(e.getMessage()))
			{
				msg = e.getMessage();
			}
			return error(msg);
		}
	}

	@GetMapping("/unauth")
	public String unauth()
	{
		return "error/unauth";
	}

	/**
	 * 调用认证接口 单点登录请求链接
	 * @param request
	 * @param response
	 * @return
	 */
	@GetMapping("/bt/oauth2/authorize")
	public String authorize(HttpServletRequest request, HttpServletResponse response)
	{
		//判断token 是否失效
		SysUser user = ShiroUtils.getSysUser();
		if (StringUtils.isNotNull(user))
		{
			return "redirect:"+successRedirectUri;
		}

		String ssoUrl = clientUrl +
				"?client_id=" +clientId +
				"&response_type=" + responseType  +
				"&redirect_uri=" + redirectUri ;

		return "redirect:"+ssoUrl;
	}

	/**
	 * 调用获取授权接口 单点登录成功跳转
	 * @param request
	 * @param response
	 * @return
	 */
	@GetMapping("/bt/loginSuccess")
	public String loginSuccess(HttpServletRequest request, HttpServletResponse response)
	{
		/**
		 * 请求模式为 POST 请求模式。
		 * 	https://loginuat.countrygarden.com.cn:8443/idp/oauth2/getToken
		 * 	参数：
		 * 	client_id= bip（由认证平台提供和上一个接口中为相同参数）
		 * 	client_secret= 91a0d83f7bc34c47bdce396833d5f388（由认证平台提供）
		 * 	code：由上一步获取 code 值
		 * 	grant_type=authorization_code
		 */
		String code = request.getParameter("code");
		Map tmap = new HashMap();
		tmap.put("client_id",clientId);
		tmap.put("client_secret",clientSecret);
		tmap.put("code",code);
		tmap.put("grant_type",grantType);
		String result = HttpUtils.sendPost(tokenUrl,tmap);
		Map map = (Map) JSONUtils.parse(result);
		String accessToken = map.get("access_token").toString();
		map.get("refresh_token");
		map.get("uid");
		map.get("expires_in");
		userInfo(response, accessToken);
		return "login";
	}

	/**
	 * 调用获取用户信息接口
	 * @param response
	 * @param accessToken
	 */
	@GetMapping("/bt/test")
	private void userInfo(HttpServletResponse response, String accessToken) {
		/**
		 * 请求模式为 GET
		 * 接口： https://loginuat.countrygarden.com.cn:8443/idp/oauth2/getUserInfo
		 * client_id=bip（由认证平台提供和上一个接口中为相同参数）
		 * access_token：由上一步获取 access_token 值
		 */
		Map userRMap = new HashMap();
		userRMap.put("client_id", clientId);
		userRMap.put("access_token", accessToken);
		String userInofResult = HttpUtils.sendGet(userInfoUrl, userRMap);
		SSoUserInfo sSoUserInfo = JSON.parseObject(userInofResult, SSoUserInfo.class);

		// 查询用户信息
		if (StringUtils.isEmpty(sSoUserInfo.getSpRoleList())) {
			logger.error("SpRoleList is null");
			try {
				String noauthUrl = nooauthUrl + "?systemName=" + clientId + "&bipName=" + URLEncoder.encode(sSoUserInfo.getDisplayName() + "【", "utf-8") + sSoUserInfo.getSpRoleList().get(0).toString() +
						URLEncoder.encode("】", "utf-8") + "&telephone=18988621234";
				response.sendRedirect(noauthUrl);
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			// TODO: 2019/5/22 测试写死
			if("wangxiongpo".equals(sSoUserInfo.getSpRoleList().get(0).toString())){
				Subject subject = SecurityUtils.getSubject();
				AuthenticationToken token1 = new UsernamePasswordToken("admin", "admin123");
				subject.login(token1);
				try {
					response.sendRedirect(successRedirectUri);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}else{
				SysUser user = userService.selectUserByLoginName(sSoUserInfo.getSpRoleList().get(0).toString());
				if(user != null){
					Subject subject = SecurityUtils.getSubject();
					AuthenticationToken token1 = new UsernamePasswordToken(user.getLoginName(), "这是sso登录账号");
					subject.login(token1);
					try {
						response.sendRedirect(successRedirectUri);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}else{
					logger.error("user not find");
					try {
						String noauthUrl = nooauthUrl+"?systemName="+clientId+"&bipName="+ URLEncoder.encode(sSoUserInfo.getDisplayName()+"【","utf-8")+sSoUserInfo.getSpRoleList().get(0).toString()+
								URLEncoder.encode("】","utf-8") +"&telephone=18988621234";

						response.sendRedirect(noauthUrl);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

}